using System.Collections;
using System.Collections.Generic;
using System.IO;
using LitJson;
using SCore.Util;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Networking;
using UnityEngine.ResourceManagement.ResourceLocations;
using UnityEngine.ResourceManagement.ResourceProviders;
using Application = UnityEngine.Device.Application;

namespace Function.HotUpdate
{
    public class HotInternalId : HotStep
    {
        private static string sAddressableUrl;
        private static string sAssetUrl;

        public override HotState GetHotState()
        {
            return HotState.InternalId;
        }

        public HotInternalId(HotContext hotContext, bool cb) : base(hotContext, cb)
        {
        }

        public string SetAssetUrl()
        {
            //http://10.0.84.152:8081/xnext/Android/1.1.1/Bundle
            var url = $"{_hotContext._addressableURL}/{_hotContext._remoteVersion}/Bundle";
            _hotContext._assettUrl = url;
            $"AssetUrl:{url}".Log();
            return url;
        }

        public void SetCustomAddress()
        {
            sAssetUrl = SetAssetUrl();
            sAddressableUrl = _hotContext._addressableURL;
        }

        protected override IEnumerator OnExecute()
        {
            _hotContext.Info("HotInternalId", "Start");
            //资源重定向

            string url = $"{Application.streamingAssetsPath}/{HotHelper.Caching}/{HotHelper.Caching}.json";
#if UNITY_EDITOR
            url = Path.GetFullPath(url);
#else
            url = $"{UnityUtils.WWWProtoHead}{url}";
#endif
            url.Log();

            var startTime = Time.unscaledTime;
            Addressables.WebRequestOverride = delegate(UnityWebRequest request)
            {
                // 有10M的资源，保险起见几乎不超时
                request.timeout = 180;
                BypassCertificate.Bypass(request);
            };
            var request = UnityWebRequest.Get(url);
            yield return request.SendWebRequest();

            var costTime = Time.unscaledTime - startTime;
            HotManager.Instance._commonTrace?.Invoke("hotfix_internal_id", new Dictionary<string, JsonData>
            {
                { "url", url },
                { "error", request.error },
                { "cost", costTime },
                { "success", string.IsNullOrEmpty(request.error) }
            });

            if (!string.IsNullOrEmpty(request.error))
            {
                _hotContext.Error($"{url} requset fair", request.error, (int)HotUpdateErrorType.LocalBundleCacheFair);
                SetSuccess(false);
                yield break;
            }

            _hotContext.Info("BundleCache:", request.downloadHandler.text);
            _bundleCacheList = JsonUtility
                .FromJson<HotHelper.Serialization<string>>(request.downloadHandler.text).ToList();
            SetCustomAddress();
            Addressables.InternalIdTransformFunc = Addressables_InternalIdTransformFunc;
            SetSuccess(true);
            _hotContext.Info("HotInternalId", "End");
            yield return Finish();
        }

        private List<string> _bundleCacheList = new();

        private string Addressables_InternalIdTransformFunc(IResourceLocation location)
        {
            if (location.Data is AssetBundleRequestOptions)
            {
                if (_bundleCacheList.Contains(location.PrimaryKey))
                {
                    var fileName = Path.GetFileName(location.PrimaryKey);

                    $"[hotupdate] trans: in StreamingAssetCache {location.PrimaryKey} {location.InternalId} {fileName}"
                        .Log();
                    return $"{Addressables.RuntimePath}/{HotHelper.Caching}/{fileName}";
                }
            }

            if (location.ResourceType == typeof(IAssetBundleResource) && location.InternalId.StartsWith("http"))
            {
                string abAddress = location.InternalId.Replace(sAddressableUrl, sAssetUrl);

                $"[hotupdate] trans: bundle {location.PrimaryKey} {location.InternalId} {location.DependencyHashCode} {abAddress}"
                    .Log();
                return abAddress;
            }

            // catalog or other no-bundle
            // 只处理hash；json会自动处理；否则json会重复处理
            if (location.InternalId.StartsWith("http") && location.InternalId.Contains(".hash"))
            {
                var addr = location.InternalId;
                // var platform = UtilsPlatform.GetBuildTargetName().ToLower();
                // 和profile匹配，谨慎调整
                addr = addr.Replace($"/catalog",
                    $"/{_hotContext.GetRemoteResVersion()}/Catalog/catalog");
                // 已经有remoteVersion，不需要再加时间戳
                // var wrappedId = HotUpdateUtils.WrapUrlWithTimePostfix(addr);
                var wrappedId = addr;
                $"[hotupdate] trans: replace {location.InternalId} to {addr} to {wrappedId}".Log();
                return wrappedId;
            }


            // XLog.Debug($"[hotupdate] trans: use origin id {location.InternalId}");
            return location.InternalId;
        }
    }
}